<template>
  <div>
    <el-row :gutter="10">
      <el-col :span="9">
        <el-tabs type="border-card">
          <el-tab-pane label="行政网格">
            <el-card class="box-card">
              <div slot="header" class="clearfix">
                <span>行政网格</span>
                <el-button
                  type="primary"
                  size="mini"
                  icon="el-icon-view"
                  class="baseBut"
                  @click.stop="() => viewAllGrid()"
                  >查看所有行政网格</el-button
                >
                <el-button
                  icon="el-icon-map-location"
                  type="success"
                  size="mini"
                  @click.stop="() => editBaseGrid({ level: 1 })"
                  >编辑单元网格</el-button
                >
                <el-button type="warning" size="mini" icon="el-icon-edit" @click="gridStyleDialog = true"
                  >修改行政级别样式</el-button
                >
              </div>
              <div>
                <div>
                  <el-input placeholder="输入关键字进行过滤" v-model="filterText" class="filter-input"> </el-input>
                </div>
                <el-tree
                  ref="tree"
                  :props="defaultProps"
                  node-key="id"
                  lazy
                  :load="loadNode"
                  :filter-node-method="filterNode"
                  class="treeBody"
                  draggable
                  @node-drop="xzDrop"
                >
                  <div class="custom-tree-node" slot-scope="{ data }">
                    <div>
                      {{ data.name }} <span v-if="data.id">（编号：{{ data.zoningCode }}）</span>
                    </div>
                    <div>
                      <el-tooltip content="查看全部子网格" placement="bottom">
                        <el-button
                          v-if="data.level > 2"
                          icon="el-icon-view"
                          type="primary"
                          size="mini"
                          @click.stop="() => viewGrid(data, 'xz')"
                        ></el-button
                      ></el-tooltip>
                      <el-tooltip content="修改网格名字" placement="bottom">
                        <el-button
                          icon="el-icon-edit"
                          type="warning"
                          size="mini"
                          @click.stop="() => editGridName(data)"
                        ></el-button
                      ></el-tooltip>
                      <el-tooltip content="编辑当前网格" placement="bottom">
                        <el-button
                          icon="el-icon-map-location"
                          type="success"
                          size="mini"
                          @click.stop="() => editGrid(data)"
                        ></el-button
                      ></el-tooltip>
                      <el-button
                        v-if="data.level > 2"
                        icon="el-icon-circle-plus-outline"
                        size="mini"
                        @click.stop="() => addGrid(data)"
                      ></el-button>
                      <el-button
                        v-if="data.level < 5"
                        icon="el-icon-delete-solid"
                        type="danger"
                        size="mini"
                        @click.stop="() => removeGrid(data)"
                      ></el-button>
                    </div>
                  </div>
                </el-tree>
              </div>
            </el-card>
          </el-tab-pane>
          <el-tab-pane label="责任网格">
            <el-card class="box-card">
              <div slot="header" class="clearfix">
                <span>责任网格</span>
                <el-button type="primary" size="mini" class="baseBut" @click.stop="() => addDutyDepa()"
                  >新增责任部门</el-button
                >
              </div>
              <div>
                <div>
                  <el-input placeholder="输入关键字进行过滤" v-model="filterDufyText" class="filter-input"> </el-input>
                </div>
                <el-tree
                  ref="dutytree"
                  :props="defaultProps"
                  node-key="id"
                  lazy
                  :load="loadDufyNode"
                  :filter-node-method="filterDufyNode"
                  class="treeBody"
                >
                  <div class="custom-tree-node" slot-scope="{ data, node }">
                    <div>
                      {{ data.departmentId ? data.adcode : data.name }}
                    </div>
                    <div>
                      <div v-if="!data.departmentId">
                        <el-tooltip content="绑定角色" placement="bottom">
                          <el-button
                            icon="el-icon-s-platform"
                            size="mini"
                            @click.stop="() => bindDepaOpen(data, node)"
                          ></el-button
                        ></el-tooltip>
                        <el-tooltip content="查看部门责任网格" placement="bottom">
                          <el-button
                            icon="el-icon-view"
                            type="primary"
                            size="mini"
                            @click.stop="() => viewGrid(data, 'zrAll')"
                          ></el-button
                        ></el-tooltip>
                        <el-button
                          icon="el-icon-circle-plus-outline"
                          size="mini"
                          @click.stop="() => addDutyGrid(data)"
                        ></el-button>
                        <el-button
                          @click="() => removeDutyDepa(data)"
                          icon="el-icon-delete"
                          size="mini"
                          type="danger"
                        ></el-button>
                      </div>
                      <div v-else>
                        <el-tooltip content="绑定人员" placement="bottom">
                          <el-button
                            icon="el-icon-user-solid"
                            size="mini"
                            @click.stop="() => bindDepaUserOpen(data)"
                          ></el-button
                        ></el-tooltip>
                        <el-tooltip content="查看网格" placement="bottom">
                          <el-button
                            icon="el-icon-view"
                            type="primary"
                            size="mini"
                            @click.stop="() => viewGrid(data, 'zr')"
                          ></el-button
                        ></el-tooltip>
                        <el-tooltip content="编辑当前网格" placement="bottom">
                          <el-button
                            icon="el-icon-map-location"
                            @click="() => editDutyGrid(data)"
                            type="success"
                            size="mini"
                          ></el-button
                        ></el-tooltip>
                        <el-button
                          v-if="data.id !== 0"
                          @click="() => removeDutyGrid(data)"
                          icon="el-icon-delete"
                          size="mini"
                          type="danger"
                        ></el-button>
                      </div>
                    </div>
                  </div>
                </el-tree>
              </div>
            </el-card>
          </el-tab-pane>
        </el-tabs>
      </el-col>
      <el-col :span="15">
        <viewGrid
          ref="viewGrid"
          :grid-type="gridType"
          :adcode="adcode"
          :level="level"
          :address-son-flag="addressSonFlag"
          :pid="pid"
          :duty-id="dutyId"
          :duty-name="dutyName"
        />
      </el-col>
    </el-row>

    <!-- 新增行政网格 -->
    <el-dialog :title="(xzForm.type == 'add' ? '新增' : '编辑') + '行政区域'" :visible.sync="xzDialog" width="400px">
      <el-form :model="xzForm" :rules="xzFormRules">
        <el-form-item label="区域名称" label-width="120px">
          <el-input v-model="xzForm.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="区域编号" label-width="120px">
          <el-input v-model="xzForm.zoningCode" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="xzDialog = false">取 消</el-button>
        <el-button type="primary" @click="addGridSub">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 绑定部门 -->
    <el-dialog title="部门绑定" :visible.sync="bindDepa.dialog" width="400px">
      <el-select v-model="bindDepa.roleId" multiple placeholder="请选择">
        <el-option v-for="item in bindDepa.selectData" :key="item.id" :label="item.roleName" :value="item.id">
        </el-option>
      </el-select>
      <div slot="footer" class="dialog-footer">
        <el-button @click="bindDepa.dialog = false">取 消</el-button>
        <el-button type="primary" @click="bindDepaSub">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 绑定人员 -->
    <el-dialog title="人员绑定" :visible.sync="bindUser.dialog" @close="bindUserClose" width="750px">
      <el-transfer
        v-model="bindUser.value"
        :data="bindUser.data"
        :titles="['全部人员', '已绑定此格人员']"
        class="transferBox"
      ></el-transfer>
      <div slot="footer" class="dialog-footer">
        <el-button @click="bindUser.dialog = false">取 消</el-button>
        <el-button type="primary" @click="bindUserSub">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 修改行政网格样式 -->
    <el-dialog title="编辑网格样式" :visible.sync="gridStyleDialog" width="500px">
      <el-form :model="gridForm" :rules="gridRules" ref="gridForm" label-width="130px" class="demo-ruleForm">
        <el-form-item label="网格层级" prop="level">
          <el-select v-model="gridForm.level" placeholder="请选择">
            <el-option v-for="item in levelOption" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="网格颜色" prop="fill">
          <el-color-picker v-model="gridForm.fill"></el-color-picker>
        </el-form-item>
        <el-form-item label="网格透明度" prop="fillOpacity">
          <el-input-number size="mini" v-model="gridForm.fillOpacity" :min="0" :max="1" :step="0.1"></el-input-number>
        </el-form-item>
        <el-form-item label="网格边界颜色" prop="stroke">
          <el-color-picker v-model="gridForm.stroke"></el-color-picker>
        </el-form-item>
        <el-form-item label="网格边界透明度" prop="strokeOpacity">
          <el-input-number
            size="mini"
            v-model="gridForm.strokeOpacity"
            :min="0.1"
            :max="1"
            :step="0.1"
          ></el-input-number>
        </el-form-item>
        <el-form-item label="网格边界宽度" prop="strokeWidth">
          <el-input-number size="mini" v-model="gridForm.strokeWidth" :min="1" :max="10"></el-input-number>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="gridStyleDialog = false">取 消</el-button>
        <el-button type="primary" @click="gridStyleSub()">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 网格地图 -->
    <gridMap
      ref="gridMap"
      :level="level"
      :pid="pid"
      :edit-power="editPower"
      :adcode="adcode"
      :grid-type="gridType"
      :grid-name="gridName"
      :address-son-flag="addressSonFlag"
    />
    <!-- 责任网格地图 -->
    <el-drawer :visible.sync="dutyDrawer" :before-close="handleClose" :with-header="false" size="95%" show-close>
      <dutyMap :state="dutyDrawer" :edit-power="editPower" :adcode="adcode" :duty-id="dutyId" />
    </el-drawer>
  </div>
</template>

<script>
import * as api from '@/api/map'
import gridMap from './gridMap.vue'
import dutyMap from './dutyMap.vue'
import viewGrid from './viewGrid.vue'
export default {
  data() {
    return {
      defaultProps: {
        children: 'children',
        label: 'name',
        isLeaf: 'isLeaf',
      },
      pid: 441322,
      adcode: '',
      level: 4,
      editPower: false,
      filterText: '',
      addressSonFlag: 'son',
      gridType: '',
      filterDufyText: '',
      dutyId: null,
      dutyName: '',
      dutyDrawer: false,
      gridName: '',
      xzForm: {
        type: 'add',
        name: '',
        zoningCode: '',
        level: null,
        pid: null,
      },
      xzFormRules: {
        name: [{ required: true, message: '请输入行政区域名字', trigger: 'blur' }],
        zoningCode: [{ required: true, message: '请输入行政区域编号', trigger: 'blur' }],
      },
      xzDialog: false,
      xzAddNode: null,
      bindDepa: {
        dialog: false,
        roleId: [],
        departmentId: null,
        selectData: [],
      },
      bindUser: {
        dialog: false,
        gridId: null,
        data: [],
        value: [],
      },
      gridStyleDialog: false,
      levelOption: [
        {
          value: 1,
          label: '单元格',
        },
        {
          value: 2,
          label: '村/居委',
        },
        {
          value: 3,
          label: '镇/街道',
        },
        {
          value: 4,
          label: '区/县',
        },
        {
          value: 5,
          label: '市级',
        },
      ],
      gridForm: {
        level: null,
        fill: '',
        fillOpacity: 0.3,
        stroke: '',
        strokeOpacity: 1,
        strokeWidth: 2,
      },
      gridRules: {
        level: [{ required: true, message: '请选择网格层级', trigger: 'change' }],
        fill: [{ required: true, message: '请选择网格颜色', trigger: 'change' }],
        fillOpacity: [{ required: true, message: '请输入网格透明度', trigger: 'blur' }],
        stroke: [{ required: true, message: '请选择边界颜色', trigger: 'change' }],
        strokeOpacity: [{ required: true, message: '请输入边界透明度', trigger: 'blur' }],
        strokeWidth: [{ required: true, message: '请输入边界宽度', trigger: 'blur' }],
      },
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    filterDufyText(val) {
      this.$refs.dutytree.filter(val)
    },
  },
  components: {
    gridMap,
    dutyMap,
    viewGrid,
  },
  created() {
    this.getRoleData()
  },
  methods: {
    // 获取责任网格列表
    async getDutyGrid(id) {
      let data = {
        departmentId: id,
      }
      let info = await api.getDepaDutyGrid(data)
      return info.data
    },
    // 获取责任部门
    async getDutyDepa() {
      let info = await api.depaList({})
      return info.data
    },
    // 责任部门懒加载
    async loadDufyNode(node, resolve) {
      if (node.level === 0) {
        let data = await this.getDutyDepa()
        return resolve(data)
      }
      if (node.level > 0) {
        let info = await this.getDutyGrid(node.data.id)
        for (const item of info) {
          item.roleId = node.data.roleIdList
          if (node.level === 1) {
            item.isLeaf = true
          }
        }
        return resolve(info)
      }
    },
    // 打开地图
    openMap() {
      this.$refs.gridMap.drawer = true
      this.$refs.gridMap.init()
    },
    // 获取行政层级
    async getCidade(pid) {
      let info = await api.getCidadeList({ pid: pid })
      return info.data
    },
    // 查看所有行政网格
    viewAllGrid() {
      this.gridType = 'All'
      this.addressSonFlag = ''
      this.editPower = false
      this.openMap()
    },
    // 编辑基础网格
    editBaseGrid(data) {
      this.gridType = 'duty'
      this.pid = null
      this.adcode = ''
      this.addressSonFlag = ''
      this.level = data.level
      this.editPower = true
      this.openMap()
    },
    // 查看行政网格
    viewGrid(data, type) {
      this.gridType = type
      if (type == 'xz') {
        // this.gridType = 'administration'
        this.pid = data.id
        this.level = data.level
        this.adcode = ''
        this.addressSonFlag = 'son'
        // this.editPower = false
        // this.openMap()
        setTimeout(() => {
          this.$refs.viewGrid.getGrid()
        }, 0)
      } else if (type == 'zrAll') {
        this.adcode = 'All'
        this.dutyId = data.id
        this.dutyName = data.name
        setTimeout(() => {
          this.$refs.viewGrid.getDutyAllGrid()
        }, 0)
      } else if (type == 'zr') {
        this.adcode = data.adcode
        setTimeout(() => {
          this.$refs.viewGrid.getDutyGrid()
        }, 0)
      }
    },
    // 编辑行政网格
    editGrid(data) {
      this.gridType = 'administration'
      this.gridName = data.name
      this.pid = data.id
      this.adcode = data.zoningCode
      this.addressSonFlag = ''
      this.level = data.level
      this.editPower = true
      this.openMap()
    },
    // 筛选
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    filterDufyNode(value, data) {
      if (!value) return true
      if (data.adcode) {
        return data.adcode.indexOf(value) !== -1
      } else {
        return data.name.indexOf(value) !== -1
      }
    },
    // 加载子数据
    async loadNode(node, resolve) {
      if (node.level === 0) {
        let data = [{ id: 441300, name: '惠州市', zoningCode: '441300000000', level: 5 }]
        return resolve(data)
      }
      if (node.level > 0) {
        let info = await this.getCidade(node.data.id)
        if (node.level === 3) {
          for (const item of info) {
            item.isLeaf = true
          }
        }
        return resolve(info)
      }
    },
    addDutyGrid(data) {
      this.$confirm('确定新增责任网格?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        api.addDutyGrid({ departmentId: data.id }).then(res => {
          if (res.code == '200') {
            let info = res.data
            info.roleId = data.roleIdList
            this.$refs.dutytree.append(res.data, data)
            this.$message({
              type: 'success',
              message: '新增成功!',
            })
          }
        })
      })
    },
    // 编辑责任网格
    editDutyGrid(data) {
      this.dutyDrawer = true
      this.adcode = data.adcode
      this.dutyId = data.id
      this.editPower = true
    },
    // 查看责任网格
    viewDutyGrid(data) {
      this.dutyDrawer = true
      this.adcode = data.adcode
      this.dutyId = data.id
      this.editPower = false
    },
    // 查看部门全部责任网格
    viewDutyAllGrid(data) {
      this.dutyDrawer = true
      this.adcode = 'All'
      this.dutyId = data.id
      this.editPower = false
    },
    // 删除责任网格
    removeDutyGrid(data) {
      this.$confirm('此操作将永久删除该责任网格, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        api.dutyGridDel([data.id]).then(res => {
          if (res.code == '200') {
            this.$refs.dutytree.remove(data)
            this.$message({
              type: 'success',
              message: '删除成功!',
            })
          }
        })
      })
    },
    // 关闭窗口
    handleClose() {
      this.dutyDrawer = false
    },
    // 移动行政地图
    xzDrop(draggingNode, dropNode, dropType) {
      let data = {
        id: draggingNode.data.id,
        level: dropType === 'inner' ? dropNode.data.level - 1 : dropNode.parent.data.level - 1,
        name: draggingNode.data.name,
        pid: dropType === 'inner' ? dropNode.data.id : dropNode.parent.data.id,
      }
      api.updateCidade(data).then(res => {
        if (res.code == '200') {
          this.$message({
            type: 'success',
            message: '移动成功!',
          })
        }
      })
    },
    // 删除行政地图
    removeGrid(data) {
      this.$confirm('此操作将永久删除该行政网格, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        api.deleteCidade({ id: data.id }).then(res => {
          if (res.code == '200') {
            this.$refs.tree.remove(data)
            this.$message({
              type: 'success',
              message: '删除成功!',
            })
          }
        })
      })
    },
    // 新增行政网格
    addGrid(data) {
      this.xzDialog = true
      this.xzForm.type = 'add'
      this.xzForm.name = ''
      this.xzForm.zoningCode = ''
      this.xzForm.level = data.level - 1
      this.xzForm.pid = data.id
      this.xzAddNode = data
    },
    // 提交新增行政网格
    addGridSub() {
      this.xzDialog = false
      let mess = ''
      api.addCidade(this.xzForm).then(res => {
        if (res.code == '200') {
          if (this.xzForm.type == 'add') {
            this.xzForm.id = res.data
            this.$refs.tree.append(this.xzForm, this.xzAddNode)
            mess = '新增成功!'
          } else {
            this.xzAddNode.name = this.xzForm.name
            this.xzAddNode.zoningCode = this.xzForm.zoningCode
            mess = '修改成功!'
          }
          this.$message({
            type: 'success',
            message: mess,
          })
          this.$data.xzForm = this.$options.data().xzForm
        }
      })
    },
    // 编辑网格名字
    editGridName(data) {
      this.xzDialog = true
      this.xzForm.type = 'edit'
      this.xzForm.name = data.name
      this.xzForm.zoningCode = data.zoningCode
      this.xzForm.id = data.id
      this.xzAddNode = data
    },
    // 新增责任部门
    addDutyDepa() {
      this.$prompt('请输入部门名称', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /^.{0,10}$/,
        inputErrorMessage: '部门名称不能超过10个字',
      }).then(({ value }) => {
        this.updateDutyDepa({ name: value })
      })
    },
    updateDutyDepa(data) {
      let tree = this.$refs.dutytree
      api.depaUpdate(data).then(res => {
        if (res.code == '200') {
          tree.insertAfter(res.data, tree.root.childNodes[tree.root.childNodes.length - 1])
          this.$message({
            type: 'success',
            message: '新增部门成功',
          })
        }
      })
    },
    // 删除责任部门
    removeDutyDepa(data) {
      this.$confirm('此操作将永久删除该部门, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        api.depaDelete({ id: data.id }).then(res => {
          if (res.code == '200') {
            this.$refs.dutytree.remove(data)
            this.$message({
              type: 'success',
              message: '删除成功!',
            })
          }
        })
      })
    },
    // 获取角色列表
    getRoleData() {
      api.getRole({ gridFlag: 'grid' }).then(res => {
        if (res.code == '200') {
          this.bindDepa.selectData = res.data
        }
      })
    },
    // 打开查询绑定部门
    bindDepaOpen(info, node) {
      let data = {
        departmentId: info.id,
      }
      this.bindDepa.dialog = true
      this.bindDepa.departmentId = info.id
      this.bindDepa.node = node
      this.bindDepa.roleId = []
      api.getDeparRole(data).then(res => {
        if (res.code == '200') {
          if (res.data.length) {
            for (const i of res.data) {
              this.bindDepa.roleId.push(i.id)
            }
          } else {
            this.bindDepa.roleId = null
          }
        }
      })
    },
    // 提交绑定部门
    bindDepaSub() {
      let that = this
      function sub(data, mess) {
        that.bindDepa.node.data.roleIdList = data.roleIds
        that.bindDepa.node.childNodes.forEach(item => {
          item.data.roleId = data.roleIds
        })
        api.bindingDepar(data).then(res => {
          if (res.code == '200') {
            that.$message({
              type: 'success',
              message: mess,
            })
            that.bindDepa.dialog = false
          }
        })
      }
      let data = { departmentId: this.bindDepa.departmentId }
      if (this.bindDepa.roleId.length) {
        data.roleIds = this.bindDepa.roleId
        sub(data, '绑定角色成功')
      } else {
        data.roleId = []
        sub(data, '解绑成功')
      }
    },
    // 打开网格绑定人员弹窗
    bindDepaUserOpen(info) {
      if (!info.roleId) {
        this.$message({
          message: '部门没有绑定角色',
          type: 'warning',
        })
        return
      }
      this.bindUser.GridId = info.id
      for (const i of info.roleId) {
        api.getRoleUser({ roleId: i }).then(res => {
          if (res.code == '200') {
            this.bindUser.dialog = true
            for (const item of res.data) {
              let dsk = {
                label: item.fullName + '-' + item.roleName,
                key: item.userId,
              }
              if (info.id === item.patrolGridId) {
                this.bindUser.value.push(item.userId)
              } else {
                dsk.disabled = Boolean(item.patrolGridId)
              }
              this.bindUser.data.push(dsk)
            }
          }
        })
      }
    },
    // 关闭网格绑定人员弹窗
    bindUserClose() {
      this.$data.bindUser = this.$options.data().bindUser
    },
    // 提交网格人员绑定
    bindUserSub() {
      let data = {
        dutyGridId: this.bindUser.GridId,
        userIds: this.bindUser.value,
      }
      api.userBindGrid(data).then(res => {
        if (res.code == '200') {
          this.$data.bindUser = this.$options.data().bindUser
          this.$message({
            type: 'success',
            message: '绑定人员成功',
          })
        }
      })
    },
    gridStyleSub() {
      api.upLevelStyle(this.gridForm).then(res => {
        if (res.code == '200') {
          this.gridStyleDialog = false
          this.$message({
            type: 'success',
            message: '修改成功',
          })
        }
      })
    },
  },
}
</script>

<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.treeBody {
  width: 100%;
  ::v-deep .el-tree-node__content {
    height: 40px;
  }
}
.transferBox {
  ::v-deep .el-transfer-panel {
    width: 250px;
  }
}
.filter-input {
  margin-left: 10px;
  width: 300px;
}
.colorBox {
  width: 30px;
  height: 30px;
  margin: 0 auto;
  border-radius: 30px;
}
.pageBox {
  margin-top: 10px;
  text-align: center;
}
.baseBut {
  margin-left: 10px;
}
</style>
